package com.ecoolex.hotel.saas.admin.graphql;

import static com.ecoolex.hotel.saas.Constant.BELONG_TYPE;
import static com.ecoolex.hotel.saas.Constant.STORE_BRAND_PARAM_KEY;
import static com.ecoolex.hotel.saas.Constant.STORE_PARAM_KEY;

import java.util.List;

import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.lang.NonNull;

import com.ecoolex.framework.common.annotation.Description;
import com.ecoolex.framework.common.enums.ResultCode;
import com.ecoolex.framework.common.pojo.Entry;
import com.ecoolex.framework.common.pojo.Page;
import com.ecoolex.framework.common.pojo.Pagination;
import com.ecoolex.framework.common.util.Assert;
import com.ecoolex.framework.common.util.Check;
import com.ecoolex.framework.modularize.api.auth.admin.AdminMemberAuthority;
import com.ecoolex.framework.modularize.api.auth.annotation.AdminAuthoritativeRegister;
import com.ecoolex.framework.modularize.api.auth.platform.PlatformMemberLoginStrategy;
import com.ecoolex.framework.modularize.api.auth.platform.PlatformMemberManager;
import com.ecoolex.framework.modularize.api.auth.platform.PlatformMemberStatus;
import com.ecoolex.framework.modularize.api.auth.platform.pojo.PlatformMemberAuthority;
import com.ecoolex.framework.modularize.api.auth.platform.pojo.PlatformMemberLoginRecord;
import com.ecoolex.framework.modularize.api.auth.platform.pojo.PlatformMemberOperLog;
import com.ecoolex.framework.modularize.api.auth.platform.pojo.QueryPlatformMember;
import com.ecoolex.framework.modularize.api.auth.platform.pojo.QueryPlatformMemberLoginRecord;
import com.ecoolex.framework.modularize.api.auth.platform.pojo.QueryPlatformMemberOperLog;
import com.ecoolex.framework.web.api.graphql2.annotation.GraphQL2Module;
import com.ecoolex.framework.web.api.graphql2.annotation.MutationField;
import com.ecoolex.framework.web.api.graphql2.annotation.QueryField;
import com.ecoolex.framework.web.api.graphql2.annotation.Source;
import com.ecoolex.framework.web.api.graphql2.annotation.TypeField;
import com.ecoolex.framework.web.api.graphql2.annotation.GraphQL2Module.Type;
import com.ecoolex.hotel.saas.admin.core.AdminConstant;
import com.ecoolex.hotel.saas.entity.Store;
import com.ecoolex.hotel.saas.entity.StoreBrand;
import com.ecoolex.hotel.saas.pojo.AddStoreBrandPlatformMember;
import com.ecoolex.hotel.saas.pojo.StoreBrandPlatformMember;
import com.ecoolex.hotel.saas.pojo.StoreBrandPlatformMemberRoleuser;
import com.ecoolex.hotel.saas.pojo.StoreBrandPlatformMemberRoleuserParam;
import com.ecoolex.hotel.saas.pojo.StoreBrandPlatformRoleuser;
import com.ecoolex.hotel.saas.ws.StoreService;
import com.google.common.collect.Lists;

@GraphQL2Module(type = Type.Admin, description = "商户品牌用户")
@AdminAuthoritativeRegister(parentKey = AdminConstant.AUTH_PROJECT_KEY,
        key = BrandMemberGraphql.AUTH,
        name = "商户品牌用户",
        remark = "商户品牌用户管理")
public class BrandMemberGraphql {

	public static final String AUTH = AdminConstant.AUTH_PROJECT_KEY + "-BRAND-MEMBER";
	
    private static final String AUTH_ADD = AUTH + "-ADD";
    
    private static final String AUTH_GET = AUTH + "-GET";
    
    private static final String AUTH_PASSWORD_UPDATE = AUTH + "-PASSWORD-UPDATE";
    
    private static final String AUTH_DISABLE = AUTH + "-DISABLE";
    
    private static final String AUTH_ENABLE = AUTH + "-ENABLE";
    
    private static final String AUTH_DEL = AUTH + "-DEL";
    
    private static final String AUTH_QUERY = AUTH + "-QUERY";
    
    private static final String AUTH_LOGIN_RECORD_QUERY = AUTH + "-LOGIN-RECORD-QUERY";
    
    private static final String AUTH_OPER_LOG_QUERY = AUTH + "-OPER-LOG-QUERY";
    
    private static final String AUTH_ROLE_QUERY = AUTH + "-ROLE-QUERY";
    
    private static final String AUTH_ROLE_SETTING = AUTH + "-ROLE-SETTING";
    
    private static final String AUTH_ROLE_UNSET = AUTH + "-ROLE-UNSET";
    
    @Autowired
    private PlatformMemberManager platformMemberManager;
    
    @Reference
	private StoreService service;
    
    // 能删除
    @TypeField(type = StoreBrandPlatformMember.class, field = "canDel", description = "是否能删除")
    public Boolean canDel(AdminMemberAuthority user) {
        return user.auth(AUTH_DEL);
    }

    // 能修改密码
    @TypeField(type = StoreBrandPlatformMember.class, field = "canUpdatePassword", description = "是否能修改密码")
    public Boolean canUpdatePassword(AdminMemberAuthority user) {
        return user.auth(AUTH_PASSWORD_UPDATE);
    }

    // 能启用
    @TypeField(type = StoreBrandPlatformMember.class, field = "canEnable", description = "是否能启用")
    public Boolean canEnable(@Source StoreBrandPlatformMember member, AdminMemberAuthority user) {
        return user.auth(AUTH_ENABLE) && Check.eq(member.getStatus(), PlatformMemberStatus.DISABLE.real());
    }

    // 能禁用
    @TypeField(type = StoreBrandPlatformMember.class, field = "canDisable", description = "是否能禁用")
    public Boolean canDisable(@Source StoreBrandPlatformMember member, AdminMemberAuthority user) {
        return user.auth(AUTH_DISABLE) && Check.eq(member.getStatus(), PlatformMemberStatus.ENABLE.real());
    }

    @TypeField(type = StoreBrandPlatformMember.class, field = "roleList", description = "角色集合")
    public List<StoreBrandPlatformMemberRoleuser> roleList(@Source StoreBrandPlatformMember member, AdminMemberAuthority user) {
        return platformMemberManager.queryPlatformMemberRoleuserByUserId(member.getUserId(),
                StoreBrandPlatformMemberRoleuser.class);
    }

    @TypeField(type = StoreBrandPlatformMemberRoleuser.class, field = "role", description = "角色详情")
    public StoreBrandPlatformRoleuser role(@Source StoreBrandPlatformMemberRoleuser source, AdminMemberAuthority user) {
        return platformMemberManager.getPlatformRoleuser(source.getRoleId(), StoreBrandPlatformRoleuser.class);
    }

    @TypeField(type = StoreBrandPlatformMemberRoleuser.class, field = "paramList", description = "角色参数")
    public List<StoreBrandPlatformMemberRoleuserParam> paramList(@Source StoreBrandPlatformMemberRoleuser source, AdminMemberAuthority user) {
        return platformMemberManager.queryPlatformMemberRoleuserParamByUserRoleId(source.getUserRoleId(),
                StoreBrandPlatformMemberRoleuserParam.class);
    }

    @TypeField(type = StoreBrandPlatformRoleuser.class, field = "authorityList", description = "角色权限列表")
    public List<PlatformMemberAuthority> authorityList(@Source StoreBrandPlatformRoleuser source, AdminMemberAuthority user) {
        return platformMemberManager.queryPlatformMemberAuthorityByRoleId(source.getRoleId());
    }
    
    @TypeField(type = StoreBrandPlatformMemberRoleuserParam.class, field = "belongStoreOrBrandName", description = "品牌用户所属商户或品牌名称")
    public String belongStoreOrBrandName(@Source StoreBrandPlatformMemberRoleuserParam source) {
    	if(Check.eqTrim(STORE_PARAM_KEY, source.getParamKey())) {
    		return service.getStore(Integer.valueOf(source.getParamValue())).getName();
    	}else if(Check.eqTrim(STORE_BRAND_PARAM_KEY, source.getParamKey())) {
    		return service.getStoreBrand(Integer.valueOf(source.getParamValue())).getName();
    	}
    	return null;
    }

    @MutationField(field = "addStoreBrandPlatformMember", description = "添加品牌账户")
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_ADD, name = "添加品牌账户")
    public StoreBrandPlatformMember add(@NonNull AddStoreBrandPlatformMember add, @NonNull Integer brandId, AdminMemberAuthority member) {
        member.assertAuth(AUTH_ADD);

        StoreBrand brand = service.getStoreBrand(brandId);
        Assert.isTrue(Check.notNull(brand), ResultCode.VERIFY.build(1), "品牌不存在");

        StoreBrandPlatformMember result
                = platformMemberManager.addMember(add, BELONG_TYPE, brandId, PlatformMemberLoginStrategy.WEB, StoreBrandPlatformMember.class, member);

        member.operationLog("AddStoreBrandPlatformMember",
                "添加品牌账户",
                Entry.create("user", result),
                Entry.create("brand", brand));

        return result;
    }

    @MutationField(field = "updateStoreBrandPlatformMemberPassword", description = "修改品牌账户密码")
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_PASSWORD_UPDATE, name = "修改品牌账户密码")
    public Boolean updatePlatformUserPassword(@NonNull Integer userId, @NonNull String password, @NonNull Integer brandId, AdminMemberAuthority member) {
        member.assertAuth(AUTH_PASSWORD_UPDATE);

        StoreBrand brand = service.getStoreBrand(brandId);
        Assert.isTrue(Check.notNull(brand), ResultCode.VERIFY.build(1), "品牌不存在");

        Assert.isTrue(canUpdatePassword(member), ResultCode.VERIFY.build(2), "不能修改用户密码");

        platformMemberManager.updatePassword(userId, password, BELONG_TYPE, brandId, member);

        member.operationLog("UpdateStoreBrandPlatformMemberPassword",
                "修改品牌账户密码",
                Entry.create("brand", brand),
                Entry.create("userId", userId));

        return true;
    }

    @MutationField(field = "disableStoreBrandPlatformMember", description = "禁用品牌账户")
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_DISABLE, name = "禁用品牌账户")
    public Boolean disableAdminUser(@NonNull Integer userId, @NonNull Integer brandId, AdminMemberAuthority member) {
        member.assertAuth(AUTH_DISABLE);

        StoreBrand brand = service.getStoreBrand(brandId);
        Assert.isTrue(Check.notNull(brand), ResultCode.VERIFY.build(1), "品牌不存在");

        platformMemberManager.disableMember(userId, BELONG_TYPE, brandId, member);

        member.operationLog("DisableStoreBrandPlatformMember",
                "禁用品牌账户",
                Entry.create("brand", brand),
                Entry.create("userId", userId));

        return true;
    }

    @MutationField(field = "enableStoreBrandPlatformMember", description = "启用品牌账户")
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_ENABLE, name = "启用品牌账户")
    public Boolean enableAdminUser(@NonNull Integer userId, @NonNull Integer brandId, AdminMemberAuthority member) {
        member.assertAuth(AUTH_ENABLE);

        StoreBrand brand = service.getStoreBrand(brandId);
        Assert.isTrue(Check.notNull(brand), ResultCode.VERIFY.build(1), "品牌不存在");

        platformMemberManager.enableMember(userId, BELONG_TYPE, brandId, member);

        member.operationLog("EnableStoreBrandPlatformMember",
                "启用品牌账户",
                Entry.create("brand", brand),
                Entry.create("userId", userId));

        return true;
    }

    @MutationField(field = "delStoreBrandPlatformMember", description = "删除品牌账户")
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_DEL, name = "删除品牌账户")
    public Boolean delUser(@NonNull Integer userId, @NonNull Integer brandId, AdminMemberAuthority member) {
        member.assertAuth(AUTH_DEL);

        StoreBrand brand = service.getStoreBrand(brandId);
        Assert.isTrue(Check.notNull(brand), ResultCode.VERIFY.build(1), "品牌不存在");

        platformMemberManager.deleteMember(userId, BELONG_TYPE, brandId, member);

        member.operationLog("DelStoreBrandPlatformMember",
                "删除品牌账户",
                Entry.create("brand", brand),
                Entry.create("userId", userId));

        return true;
    }

    @QueryField(field = "storeBrandPlatformMember", description = "品牌账户详情")
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_GET, name = "品牌账户详情")
    public StoreBrandPlatformMember get(@NonNull Integer userId, @NonNull Integer brandId, AdminMemberAuthority member) {
        member.assertAuth(AUTH_GET);

        StoreBrand brand = service.getStoreBrand(brandId);
        Assert.isTrue(Check.notNull(brand), ResultCode.VERIFY.build(1), "品牌不存在");

        return platformMemberManager.getMember(userId, BELONG_TYPE, brandId, StoreBrandPlatformMember.class);
    }

    @QueryField(field = "storeBrandPlatformMemberList", description = "品牌账户列表")
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_QUERY, name = "查询品牌账户列表")
    public Pagination<StoreBrandPlatformMember> query(@NonNull QueryPlatformMember query, @NonNull Page page, Integer brandId, AdminMemberAuthority member) {
        member.assertAuth(AUTH_QUERY);
        return platformMemberManager.query(query, page, BELONG_TYPE, brandId, StoreBrandPlatformMember.class, member);
    }

    @QueryField(field = "storeBrandPlatformMemberLoginRecordList", description = "查询品牌账户登录记录")
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_LOGIN_RECORD_QUERY, name = "查询品牌账户登录记录")
    public Pagination<PlatformMemberLoginRecord> queryPlatformLoginRecord(@NonNull Integer userId, Integer brandId, @NonNull QueryPlatformMemberLoginRecord query, @NonNull Page page, AdminMemberAuthority member) {
        member.assertAuth(AUTH_LOGIN_RECORD_QUERY);
        return platformMemberManager.queryMemberLoginRecord(userId, BELONG_TYPE, brandId, query, page, member);
    }

    @QueryField(field = "storeBrandPlatformMemberOperLogList", description = "查询品牌账户户操作日志")
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_OPER_LOG_QUERY, name = "查询品牌账户操作日志")
    public Pagination<PlatformMemberOperLog> queryPlatformOperLog(@NonNull Integer userId, Integer brandId, @NonNull QueryPlatformMemberOperLog query, @NonNull Page page, AdminMemberAuthority member) {
        member.assertAuth(AUTH_OPER_LOG_QUERY);
        return platformMemberManager.queryMemberOperLog(userId, BELONG_TYPE, brandId, query, page, member);
    }

    @QueryField(field = "storeBrandPlatformRoleuserList", description = "查询商户品牌角色列表")
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_ROLE_QUERY, name = "查询品牌账户操作日志")
    public Pagination<StoreBrandPlatformRoleuser> queryStoreBrandRole(Integer brandId, String keyword, Page page, AdminMemberAuthority member) {
        member.assertAuth(AUTH_ROLE_QUERY);

        StoreBrand brand = service.getStoreBrand(brandId);
        Assert.isTrue(Check.notNull(brand), ResultCode.VERIFY.build(1), "品牌不存在");
        return platformMemberManager.queryRoleuser(keyword,
                Lists.newArrayList(STORE_PARAM_KEY, STORE_BRAND_PARAM_KEY),
                BELONG_TYPE,
                brandId,
                page,
                StoreBrandPlatformRoleuser.class);
    }

    @MutationField(field = "settingStoreBrandPlatformMemberRoleuser", description = "设置商户品牌账户角色")
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_ROLE_SETTING, name = "设置商户品牌账户角色")
    public Boolean settingStoreBrandPlatformRoleuser(@NonNull Integer userId, @NonNull Integer roleId, @NonNull Integer brandId, @Description({
            "角色所需参数值"}) String paramValue, AdminMemberAuthority user) {
        user.assertAuth(AUTH_ROLE_SETTING);

        StoreBrand brand = service.getStoreBrand(brandId);
        Assert.isTrue(Check.notNull(brand), ResultCode.VERIFY.build(1), "品牌不存在");
        StoreBrandPlatformRoleuser roleuser
                = platformMemberManager.getPlatformRoleuser(roleId, BELONG_TYPE, brandId, StoreBrandPlatformRoleuser.class);
        Assert.isTrue(Check.notNull(roleuser), ResultCode.VERIFY.build(2), "品牌下角色不存在");
        StoreBrandPlatformMember member
                = platformMemberManager.getMember(userId, BELONG_TYPE, brandId, StoreBrandPlatformMember.class);
        Assert.isTrue(Check.notNull(member), ResultCode.VERIFY.build(3), "品牌下用户不存在");
        if (Check.eq(roleuser.getNeedParamKey(), STORE_PARAM_KEY)) {
            // 商户参数
            Assert.isTrue(Check.notNullOrTrimEmpty(paramValue), ResultCode.VERIFY.build(4), "参数值不能为空");
            Store store = service.getStore(Integer.valueOf(paramValue));
            Assert.isTrue(Check.notNull(store), ResultCode.VERIFY.build(5), "商户不存在");
            // 检查品牌下是否存在该商户
            Assert.isTrue(Check.eq(store.getBrandId(), brandId), ResultCode.VERIFY.build(6), "品牌下商户不存在");
            platformMemberManager.settingPlatformRoleuser(roleuser, member, paramValue, user.userName());
            user.operationLog("AddStoreBrandPlatformMemberRoleuser",
                    "账户添加商户角色",
                    Entry.create("brand", brand),
                    Entry.create("store", store),
                    Entry.create("roleuser", roleuser),
                    Entry.create("member", member));
        } else if (Check.eq(roleuser.getNeedParamKey(), STORE_BRAND_PARAM_KEY)) {
            // 品牌
            platformMemberManager.settingPlatformRoleuser(roleuser, member, String.valueOf(brandId), user.userName());
            user.operationLog("AddStoreBrandPlatformMemberRoleuser",
                    "账户添加商户品牌角色",
                    Entry.create("brand", brand),
                    Entry.create("roleuser", roleuser),
                    Entry.create("member", member));
        } else {
            Assert.isTrue(Check.notNull(roleuser), ResultCode.VERIFY.build(7), "无法配置的角色");
        }
        return true;
    }

    @MutationField(field = "unsetStoreBrandPlatformMemberRoleuser", description = "复原商户品牌账户角色")
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_ROLE_UNSET, name = "复原商户品牌账户角色")
    public Boolean unsetStoreBrandPlatformMemberRoleuser(@NonNull Integer userRoleId, @NonNull Integer brandId, AdminMemberAuthority user) {
        user.assertAuth(AUTH_ROLE_UNSET);

        StoreBrandPlatformMemberRoleuser memberRoleuser
                = platformMemberManager.getPlatformMemberRoleuser(userRoleId, StoreBrandPlatformMemberRoleuser.class);
        Assert.isTrue(Check.notNull(memberRoleuser), ResultCode.VERIFY.build(7), "用户角色不存在");
        StoreBrandPlatformMember member = platformMemberManager.getMember(memberRoleuser.getUserId(),
                BELONG_TYPE,
                brandId,
                StoreBrandPlatformMember.class);
        Assert.isTrue(Check.notNull(member), ResultCode.VERIFY.build(7), "品牌下不存在该用户");

        platformMemberManager.unsetPlatformRoleuser(memberRoleuser, user.userName());

        return true;
    }
}
